package logTest

import (
	"errors"
	"fmt"
	"os"
)

var LogFile LogI

type FileName uint8

const (
	FileInfo FileName = iota
	FileErr
	FileRegister
)

type logf struct {
	fdList map[FileName]*os.File
}

func init() {
	LogFile = &logf{}
}

func NewLogWithFile(filePaths map[FileName]string) {
	fdList := make(map[FileName]*os.File)
	for k, v := range filePaths {
		f, err := os.OpenFile(v, os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_APPEND, 0644)
		if err != nil {
			fmt.Println("初始化文件发生异常")
			os.Exit(1)
		}
		fdList[k] = f
	}
	l := &logf{}
	l.fdList = fdList
	LogFile = l
}

func (l *logf) Debug(message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write("DEBUG", msg)
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) Info(message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write("INFO", msg)
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) Warn(message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write("WARN", msg)
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) Error(message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write("ERROR", msg)
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) Panic(message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write("PANIC", msg)
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) Println(level string, message ...interface{}) {
	if l.fdList == nil {
		fmt.Println("文件未初始化")
		return
	}
	f, msg, err := l.checkFilePath(message...)
	if err != nil {
		fmt.Println(err)
		return
	}
	outMsg := write(level, msg)
	if outMsg == "" {
		fmt.Println("错误的日志级别：", level)
		return
	}
	outMsg += "\n"
	f.WriteString(outMsg)
}

func (l *logf) writeFile(fileName FileName, fileContext string) {
	if v, ok := l.fdList[fileName]; !ok {
		fmt.Println("错误的文件名")
		return
	} else {
		v.WriteString(fileContext + "\n")
	}
}

func (l *logf) checkFilePath(message ...interface{}) (f *os.File, msg interface{}, err error) {
	var filePath interface{}
	for k, v := range message {
		if k == 0 {
			filePath = v
		}
	}
	switch filePath.(type) {
	case FileName:
		if v, ok := l.fdList[filePath.(FileName)]; !ok {
			err = errors.New("不存在的文件名")
			return
		} else {
			f = v
			msg = message[1:]
		}
	default:
		err = errors.New("错误的文件名")
		return
	}
	return
}

func (l *logf) Close() {
	for _, v := range l.fdList {
		v.Close()
	}
}
